package com.example.filedownload.filedownload;

import com.example.filedownload.CacheEntity;
import com.example.filedownload.Util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

public class DownloadManager implements Runnable {  // 保存路径
    private String savePath;

    private int threadNum;
    private String urlFile;
    private boolean isStarted;
    private List<DownloadThread> downloadList = new ArrayList<>();

    public DownloadManager(String savePath, int threadNum, String urlFile) {
        super();
        this.savePath = savePath;
        this.threadNum = threadNum;
        this.urlFile = urlFile;
    }

    public void action() {
        new Thread(this).start();
    }

    public void run() {
        long t1 = System.currentTimeMillis();
        System.out.println(t1);
        if (!isStarted) {
            startDownload();
            isStarted = true;
        }
        while (true) {
            boolean finish = true;
            for (DownloadThread thread : downloadList) {
                if (!thread.isFinish()) {
                    finish = false;
                    break;
                }
            }
            if (finish) {
                mergeFiles();
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2);
        System.out.println("下载用时：" + (t2 - t1));
    }

    public void startDownload() {
        int[][] posAndLength = getPosAndLength();
        for (int i = 0; i < posAndLength.length; i++) {
            int pos = posAndLength[i][0];
            int length = posAndLength[i][1];
            DownloadThread downloadThread = new DownloadThread(i + 1, length, pos, savePath, urlFile);
            new Thread(downloadThread).start();
            downloadList.add(downloadThread);
        }
    }

    /**
     * 获得文件大小  *   * @return 文件大小
     */
    public long getFileLength() {
        System.out.println("获得文件大小 start......");
        HttpURLConnection conn = null;
        long result = 0;
        try {
            URL url = new URL(urlFile);
            conn = (HttpURLConnection) url.openConnection();
            result = Long.parseLong(conn.getHeaderField("Content-Length"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        System.out.println("获得文件大小 end......" + result);
        return result;
    }

    public int[][] getPosAndLength() {
        int[][] result = new int[threadNum][2];
        int fileLength = (int) getFileLength();
        int every = fileLength % threadNum == 0 ? fileLength / threadNum : fileLength / threadNum + 1;
        for (int i = 0; i < result.length; i++) {
            int length = 0;
            if (i != result.length - 1) {
                length = every;
            } else {
                length = fileLength - i * every;
            }
            result[i][0] = i * every;
            result[i][1] = length;
        }
        return result;
    }

    public void mergeFiles() {
        System.out.println("合并文件 start......");
        OutputStream out = null;
        try {
            out = new FileOutputStream(savePath);
            for (int i = 1; i <= threadNum; i++) {
                InputStream in = new FileInputStream(savePath + i);
                byte[] bytes = new byte[2048];
                int read = 0;
                while ((read = in.read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                    out.flush();
                }
                if (in != null) {
                    in.close();
                    new File(savePath + i).delete();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("合并文件 end......");
        CacheEntity.getSingleTon().setIsSuccess(true);
        CacheEntity.getSingleTon().setDownloadSize(new AtomicLong(0));
        Util.openExplorer();
    }

    public String getSavePath() {
        return savePath;
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }

    public int getThreadNum() {
        return threadNum;
    }

    public void setThreadNum(int threadNum) {
        this.threadNum = threadNum;
    }

    public String getUrlFile() {
        return urlFile;
    }

    public void setUrlFile(String urlFile) {
        this.urlFile = urlFile;
    }

    public boolean isStarted() {
        return isStarted;
    }

    public void setStarted(boolean isStarted) {
        this.isStarted = isStarted;
    }

    public List<DownloadThread> getDownloadList() {
        return downloadList;
    }

    public void setDownloadList(List<DownloadThread> downloadList) {
        this.downloadList = downloadList;
    }
}